package com.hzncc.flowable_diboot.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diboot.core.holder.ThreadLocalHolder;
import com.diboot.core.service.impl.BaseServiceImpl;
import com.diboot.core.util.BeanUtils;
import com.diboot.iam.entity.IamUser;
import com.diboot.iam.entity.IamUserRole;
import com.diboot.iam.service.IamUserRoleService;
import com.diboot.iam.util.IamSecurityUtils;
import com.diboot.tenant.entity.IamTenant;
import com.diboot.tenant.service.IamTenantService;
import com.hzncc.flowable_diboot.entity.RoleTenant;
import com.hzncc.flowable_diboot.mapper.RoleTenantMapper;
import com.hzncc.flowable_diboot.service.RoleTenantService;
import com.hzncc.flowable_diboot.util.ConstantUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 角色租户 相关Service实现类
 *
 * @author MyName
 * @version 1.0
 * @date 2024-08-08
 * Copyright © MyCorp
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class RoleTenantServiceImpl extends BaseServiceImpl<RoleTenantMapper, RoleTenant> implements RoleTenantService {
    private final RoleTenantMapper roleTenantMapper;
    private final IamUserRoleService iamUserRoleService;
    private final IamTenantService iamTenantService;
    private final CacheManager cacheManager;

    /**
     * 获取角色可访问租户
     *
     * @param role 角色id
     * @return
     */
    public List<String> getRoleAccessibleTenant(String role) {
        Cache cache = cacheManager.getCache(ConstantUtil.CACHE_ROLE_TENANT);
        List<String> list = cache.get(role, List.class);
        if (list != null && list.size() > 0) {
            return list;
        }
        QueryWrapper<RoleTenant> qw = new QueryWrapper<>();
        qw.lambda().select(RoleTenant::getTargetTenant).eq(RoleTenant::getRole, role);
        // todo 是否区分租户
        //qw.lambda().eq(RoleTenant::getTenantId, IamSecurityUtils.getCurrentTenantId());
        List<RoleTenant> roleTenants = roleTenantMapper.selectList(qw);
        List<String> res = roleTenants.stream().map(RoleTenant::getTargetTenant).collect(Collectors.toList());
        cache.put(role, res);
        return res;
    }

    /**
     * 获取用户角色
     *
     * @param userId 用户id
     * @return
     */
    public List<String> getRoleIds(String userId) {
        Cache cache = cacheManager.getCache(ConstantUtil.CACHE_USER_ROLE);
        List list = cache.get(userId, List.class);
        if (list != null && list.size() > 0) {
            return list;
        }
        QueryWrapper<IamUserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(IamUserRole::getUserId, userId);
        ThreadLocalHolder.setIgnoreInterceptor();
        List<IamUserRole> userRoleList = iamUserRoleService.getEntityList(queryWrapper);
        List<String> res = userRoleList.stream().map(IamUserRole::getRoleId).collect(Collectors.toList());
        cache.put(userId, res);
        return res;
    }

    @Override
    public List<Expression> getAccessibleTenant() {
        // 获取当前用户
        IamUser user = IamSecurityUtils.getCurrentUser();
        // 如果用户为空，则返回租户id为0
        if (user == null) {
            return Arrays.asList(new StringValue("0"));
        }
        // 获取当前租户
        IamTenant tenant = iamTenantService.getEntity(user.getTenantId());
        // 如果租户不允许跨租户，则返回租户id
        if (tenant.getCrossTenant() != 1) {
            return Arrays.asList(new StringValue(user.getTenantId()));
        }
        // 获取用户角色
        List<String> roleIds = getRoleIds(user.getId());
        List<String> tenantList = new ArrayList<>();
        // 遍历角色，获取角色可访问租户
        for (String roleId : roleIds) {
            List<String> roleAccessibleTenant = getRoleAccessibleTenant(roleId);
            if (roleAccessibleTenant.size() > 0) {
                tenantList.addAll(roleAccessibleTenant);
            }
        }
        // 添加当前租户
        tenantList.add(user.getTenantId());
        List<String> collect = tenantList.stream().distinct().collect(Collectors.toList());
        // 转换为表达式
        List<Expression> expressions = new ArrayList<>();
        for (String s : collect) {
            expressions.add(new StringValue(s));
        }
        return expressions;
    }

    @Override
    public List<String> getAccessibleTenantWithString() {
        // 获取当前用户
        IamUser user = IamSecurityUtils.getCurrentUser();
        // 如果用户为空，则返回租户id为0
        if (user == null) {
            return Arrays.asList("0");
        }
        // 获取当前租户
        IamTenant tenant = iamTenantService.getEntity(user.getTenantId());
        // 如果租户不允许跨租户，则返回租户id
        if (tenant.getCrossTenant() != 1) {
            return Arrays.asList(user.getTenantId());
        }
        // 获取用户角色
        List<String> roleIds = getRoleIds(user.getId());
        List<String> tenantList = new ArrayList<>();
        // 遍历角色，获取角色可访问租户
        for (String roleId : roleIds) {
            List<String> roleAccessibleTenant = getRoleAccessibleTenant(roleId);
            if (roleAccessibleTenant.size() > 0) {
                tenantList.addAll(roleAccessibleTenant);
            }
        }
        // 添加当前租户
        tenantList.add(user.getTenantId());
        List<String> collect = tenantList.stream().distinct().collect(Collectors.toList());

        return collect;
    }

    @Override
    public void updateTenant(String id, List<String> tenantIdList) {
        Cache cache = cacheManager.getCache(ConstantUtil.CACHE_ROLE_TENANT);
        if (cache != null) {
            cache.evict(id);
        }
        if (tenantIdList == null) {
            tenantIdList = new ArrayList<>();
        }
        QueryWrapper<RoleTenant> qw = new QueryWrapper<>();
        qw.lambda().eq(RoleTenant::getRole, id);
        List<RoleTenant> entityList = getEntityList(qw);
        List<String> tenantIds = BeanUtils.collectToList(entityList, RoleTenant::getTargetTenant);
        // 筛选出新增的租户
        List<String> addTenantIds = tenantIdList.stream().filter(tenantId -> !tenantIds.contains(tenantId)).toList();
        // 筛选出删除的租户
        List<String> finalTenantIdList = tenantIdList;
        List<String> deleteTenantIds = tenantIds.stream().filter(tenantId -> !finalTenantIdList.contains(tenantId)).toList();
        List<String> delIds = entityList.stream().filter(e -> deleteTenantIds.contains(e.getTargetTenant())).map(RoleTenant::getId).toList();
        deleteEntities(delIds);
        // 新增租户
        for (String tenantId : addTenantIds) {
            RoleTenant roleTenant = new RoleTenant();
            roleTenant.setRole(id);
            roleTenant.setTargetTenant(tenantId);
            createEntity(roleTenant);
        }
    }


}